//! 媒体处理工具
//! 
//! 提供图像、音视频处理功能

use image::ImageFormat;
use std::path::Path;

/// 媒体错误类型
#[derive(Debug, thiserror::Error)]
pub enum MediaError {
    #[error("Image error: {0}")]
    ImageError(#[from] image::ImageError),
    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error),
    #[error("Unsupported format: {0}")]
    UnsupportedFormat(String),
    #[error("File not found: {0}")]
    FileNotFound(String),
}

pub type MediaResult<T> = Result<T, MediaError>;

/// 图像信息结构体
#[derive(Debug, Clone)]
pub struct ImageInfo {
    pub width: u32,
    pub height: u32,
    pub format: String,
    pub size_bytes: u64,
}

/// 获取图像尺寸
/// 
/// # Examples
/// ```
/// use librarys::io::get_image_size;
/// 
/// // 注意：这需要一个存在的图像文件
/// // let (width, height) = get_image_size("test.jpg").unwrap();
/// // assert!(width > 0 && height > 0);
/// ```
pub fn get_image_size(path: &str) -> MediaResult<(u32, u32)> {
    let path = Path::new(path);
    
    if !path.exists() {
        return Err(MediaError::FileNotFound(path.display().to_string()));
    }
    
    let img = image::open(path)?;
    Ok((img.width(), img.height()))
}

/// 获取详细图像信息
/// 
/// # Examples
/// ```
/// use librarys::io::get_image_info;
/// 
/// // let info = get_image_info("test.jpg").unwrap();
/// // assert!(info.width > 0);
/// // assert!(!info.format.is_empty());
/// ```
pub fn get_image_info(path: &str) -> MediaResult<ImageInfo> {
    let path = Path::new(path);
    
    if !path.exists() {
        return Err(MediaError::FileNotFound(path.display().to_string()));
    }
    
    let img = image::open(path)?;
    let metadata = std::fs::metadata(path)?;
    
    // 推断文件格式
    let format = match path.extension().and_then(|ext| ext.to_str()) {
        Some("jpg") | Some("jpeg") => "JPEG".to_string(),
        Some("png") => "PNG".to_string(),
        Some("gif") => "GIF".to_string(),
        Some("bmp") => "BMP".to_string(),
        Some("webp") => "WebP".to_string(),
        Some(ext) => ext.to_uppercase(),
        None => "Unknown".to_string(),
    };
    
    Ok(ImageInfo {
        width: img.width(),
        height: img.height(),
        format,
        size_bytes: metadata.len(),
    })
}

/// 图像格式转换
/// 
/// # Examples
/// ```
/// use librarys::io::convert_image_format;
/// 
/// // convert_image_format("input.jpg", "output.png", "png").unwrap();
/// ```
pub fn convert_image_format(input: &str, output: &str, format: &str) -> MediaResult<()> {
    let input_path = Path::new(input);
    let output_path = Path::new(output);
    
    if !input_path.exists() {
        return Err(MediaError::FileNotFound(input_path.display().to_string()));
    }
    
    let img = image::open(input_path)?;
    
    let format = match format.to_lowercase().as_str() {
        "jpg" | "jpeg" => ImageFormat::Jpeg,
        "png" => ImageFormat::Png,
        "gif" => ImageFormat::Gif,
        "bmp" => ImageFormat::Bmp,
        "webp" => ImageFormat::WebP,
        "tiff" => ImageFormat::Tiff,
        "ico" => ImageFormat::Ico,
        _ => return Err(MediaError::UnsupportedFormat(format.to_string())),
    };
    
    img.save_with_format(output_path, format)?;
    Ok(())
}

/// 图像缩放
/// 
/// # Examples
/// ```
/// use librarys::io::resize_image;
/// 
/// // resize_image("input.jpg", "output.jpg", 800, 600).unwrap();
/// ```
pub fn resize_image(input: &str, output: &str, width: u32, height: u32) -> MediaResult<()> {
    let input_path = Path::new(input);
    let output_path = Path::new(output);
    
    if !input_path.exists() {
        return Err(MediaError::FileNotFound(input_path.display().to_string()));
    }
    
    let img = image::open(input_path)?;
    let resized = img.resize(width, height, image::imageops::FilterType::Lanczos3);
    
    resized.save(output_path)?;
    Ok(())
}

/// 图像旋转
/// 
/// # Examples
/// ```
/// use librarys::io::rotate_image;
/// 
/// // rotate_image("input.jpg", "output.jpg", 90).unwrap();
/// ```
pub fn rotate_image(input: &str, output: &str, degrees: i32) -> MediaResult<()> {
    let input_path = Path::new(input);
    let output_path = Path::new(output);
    
    if !input_path.exists() {
        return Err(MediaError::FileNotFound(input_path.display().to_string()));
    }
    
    let img = image::open(input_path)?;
    
    let rotated = match degrees {
        90 | -270 => img.rotate90(),
        180 | -180 => img.rotate180(),
        270 | -90 => img.rotate270(),
        _ => return Err(MediaError::UnsupportedFormat(format!("Unsupported rotation: {} degrees", degrees))),
    };
    
    rotated.save(output_path)?;
    Ok(())
}

/// 图像裁剪
/// 
/// # Examples
/// ```
/// use librarys::io::crop_image;
/// 
/// // crop_image("input.jpg", "output.jpg", 100, 100, 200, 200).unwrap();
/// ```
pub fn crop_image(input: &str, output: &str, x: u32, y: u32, width: u32, height: u32) -> MediaResult<()> {
    let input_path = Path::new(input);
    let output_path = Path::new(output);
    
    if !input_path.exists() {
        return Err(MediaError::FileNotFound(input_path.display().to_string()));
    }
    
    let img = image::open(input_path)?;
    let cropped = img.crop_imm(x, y, width, height);
    
    cropped.save(output_path)?;
    Ok(())
}

/// 生成缩略图
/// 
/// # Examples
/// ```
/// use librarys::io::generate_thumbnail;
/// 
/// // generate_thumbnail("input.jpg", "thumb.jpg", 150).unwrap();
/// ```
pub fn generate_thumbnail(input: &str, output: &str, max_size: u32) -> MediaResult<()> {
    let input_path = Path::new(input);
    let output_path = Path::new(output);
    
    if !input_path.exists() {
        return Err(MediaError::FileNotFound(input_path.display().to_string()));
    }
    
    let img = image::open(input_path)?;
    let thumbnail = img.thumbnail(max_size, max_size);
    
    thumbnail.save(output_path)?;
    Ok(())
}

/// 图像反色（黑白）
/// 
/// # Examples
/// ```
/// use librarys::io::invert_image;
/// 
/// // invert_image("input.jpg", "output.jpg").unwrap();
/// ```
pub fn invert_image(input: &str, output: &str) -> MediaResult<()> {
    let input_path = Path::new(input);
    let output_path = Path::new(output);
    
    if !input_path.exists() {
        return Err(MediaError::FileNotFound(input_path.display().to_string()));
    }
    
    let mut img = image::open(input_path)?;
    img.invert();
    
    img.save(output_path)?;
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;

    fn create_test_image(path: &std::path::Path, width: u32, height: u32) -> MediaResult<()> {
        use image::{RgbImage, Rgb, DynamicImage};
        
        let img = RgbImage::from_fn(width, height, |x, y| {
            if (x + y) % 2 == 0 {
                Rgb([255, 0, 0]) // 红色
            } else {
                Rgb([0, 255, 0]) // 绿色
            }
        });
        
        let dynamic_img = DynamicImage::ImageRgb8(img);
        dynamic_img.save(path)?;
        Ok(())
    }

    #[test]
    fn test_image_info() {
        let temp_dir = TempDir::new().unwrap();
        let test_image_path = temp_dir.path().join("test.png");
        
        // 创建测试图像
        create_test_image(&test_image_path, 100, 50).unwrap();
        
        let info = get_image_info(test_image_path.to_str().unwrap()).unwrap();
        assert_eq!(info.width, 100);
        assert_eq!(info.height, 50);
        assert_eq!(info.format, "PNG");
        assert!(info.size_bytes > 0);
    }

    #[test]
    fn test_image_size() {
        let temp_dir = TempDir::new().unwrap();
        let test_image_path = temp_dir.path().join("test.png");
        
        create_test_image(&test_image_path, 200, 100).unwrap();
        
        let (width, height) = get_image_size(test_image_path.to_str().unwrap()).unwrap();
        assert_eq!(width, 200);
        assert_eq!(height, 100);
    }

    #[test]
    fn test_image_format_conversion() {
        let temp_dir = TempDir::new().unwrap();
        let input_path = temp_dir.path().join("input.png");
        let output_path = temp_dir.path().join("output.jpg");
        
        create_test_image(&input_path, 50, 50).unwrap();
        
        let result = convert_image_format(
            input_path.to_str().unwrap(),
            output_path.to_str().unwrap(),
            "jpg"
        );
        
        assert!(result.is_ok());
        assert!(output_path.exists());
    }

    #[test]
    fn test_image_resize() {
        let temp_dir = TempDir::new().unwrap();
        let input_path = temp_dir.path().join("input.png");
        let output_path = temp_dir.path().join("resized.png");
        
        create_test_image(&input_path, 100, 100).unwrap();
        
        let result = resize_image(
            input_path.to_str().unwrap(),
            output_path.to_str().unwrap(),
            50,
            50  // 使用相同的宽高比例避免图像失真
        );
        
        assert!(result.is_ok());
        assert!(output_path.exists());
        
        let (width, height) = get_image_size(output_path.to_str().unwrap()).unwrap();
        assert_eq!(width, 50);
        assert_eq!(height, 50);
    }

    #[test]
    fn test_file_not_found() {
        let result = get_image_size("nonexistent.jpg");
        assert!(result.is_err());
        assert!(matches!(result.unwrap_err(), MediaError::FileNotFound(_)));
    }
}